package com.health.mapp.impl;


import java.math.BigDecimal;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import com.health.commons.MD5;
import com.health.db.model.GoodsOrder;
import com.health.db.model.GoodsOrderContact;
import com.health.db.service.order.IRegisterOrderService;
import com.health.db.service.order.ISubRegisterOrderService;
import com.health.db.service.sm.IGoodsGiftListService;
import com.health.db.service.sm.IGoodsOrderService;
import com.health.db.service.sm.IWXPayService;
import com.health.db.service.user.IGoodsPriceListService;
import com.health.db.service.user.IUserCardListService;
import com.health.mapp.bean.Header;
import com.health.mapp.bean.PayControllerWXMiNiReq;
import com.health.mapp.bean.PayControllerWXMiNiResp;
import com.health.mapp.interImpl.PayActionServerImpl;
import com.health.mapp.utils.Constant;
import com.health.mapp.utils.DateUtils;
import com.health.mapp.utils.Response;
import com.health.mapp.utils.ResultCode;
import com.health.pay.tencent.common.Signature;
import com.health.pay.tencent.protocol.unifiedorder.UnifiedorderResData;

/**
 * 微信订单串获取
 * 
 * @author yuchong
 * 
 * @pramati private Long orderId; //订单号
 * 
 */
public class PayControllerWXMiNiImpl implements ActionInterface {

	private static final Logger logger = Logger.getLogger(PayControllerWXImpl.class);

	// service import
	private IRegisterOrderService registerOrderService;
	private IGoodsPriceListService goodsPriceListService;
	private IWXPayService wXPayService;
	private ISubRegisterOrderService subRegisterOrderService;
	private IGoodsOrderService goodsOrderService;
	private IUserCardListService userCardListService;
	
	/**
	 * @return the wXPayService
	 */
	public IWXPayService getwXPayService() {
		return wXPayService;
	}

	/**
	 * @param wXPayService
	 *            the wXPayService to set
	 */
	public void setwXPayService(IWXPayService wXPayService) {
		this.wXPayService = wXPayService;
	}
	
	@Override
	public Response execute(Header header, Object reqBean) throws Exception {

		PayControllerWXMiNiReq req = (PayControllerWXMiNiReq) reqBean;
		PayControllerWXMiNiResp _resp = new PayControllerWXMiNiResp();
		Long orderId = req.getOrderId();
		
		String goodsId = req.getGoodsId();
		String userId = req.getUserId();

		if (StringUtils.isNotBlank(goodsId)&&StringUtils.isNotBlank(userId)) {
			//type =0 新增  1 修改   
			
			GoodsOrder goodsOrder = new GoodsOrder();
			goodsOrder.setOwnerid(Long.valueOf(userId));
			goodsOrder.setGoodsid(Long.valueOf(goodsId));
			goodsOrder.setOwenerName(req.getUserName());
			//待支付状态
			goodsOrder.setRunstatusid(Constant.CONSTANTS_ORDER_RUNSTATUS_ID_1);
			goodsOrder.setRunStatus(Constant.CONSTANTS_ORDER_RUNSTATUS_DES_1);
			goodsOrder.setPayFlag(String.valueOf(Constant.CONSTANTS_IS_PAYMENT_FALSE));
			goodsOrder.setPayTypeId(Constant.CONSTANTS_IS_PAYMENT_FALSE);
			
			if(StringUtils.isNotBlank(req.getContactPhone())){
				GoodsOrderContact  goodsOrderContact = new GoodsOrderContact();
				goodsOrderContact.setOwnerId(Long.valueOf(userId));
				goodsOrderContact.setContactPhone(req.getContactPhone());
				goodsOrderContact.setContactAddress(req.getContactAddress());
				goodsOrderContact.setContactName(req.getContactName());
				//	goodsOrderContact.setChannel(req.getChannel());
				
				if (StringUtils.isEmpty(req.getChannel())||"null".equals(req.getChannel())) {
					goodsOrderContact.setChannel(String.valueOf("1"));
				    	
				}else{
					goodsOrderContact.setChannel(req.getChannel());
				}
				
				goodsOrder =goodsOrderService.insertCourse(goodsOrder,goodsOrderContact);
			}else{
				goodsOrder =goodsOrderService.insert(goodsOrder);
			}
			
			
			
			if (null==goodsOrder.getRecid()) {
				 
				_resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3001);
				_resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3001_NOTE);
			}else{
				
				orderId = goodsOrder.getRecid();
				
			}
		}else{
			
			_resp.setErrorCode(ResultCode.OPERATION_LAKE_PARAMETER_ERROR);
			_resp.setErrorMsg(ResultCode.OPERATION_LAKE_PARAMETER_ERROR_NOTE);
			return _resp;
		}
		
		
		
		if (orderId == 0) {
			_resp.setErrorCode(ResultCode.OPERATION_LAKE_PARAMETER_ERROR);
			_resp.setErrorMsg(ResultCode.OPERATION_LAKE_PARAMETER_ERROR_NOTE);
			return _resp;
		} else {
			
			String goodsName="";
			BigDecimal orderFee =new BigDecimal(0);
			String temOrderId = String.valueOf(orderId); // 订单号
			
			temOrderId=temOrderId+"-"+String.valueOf(Constant.CONSTANTS_PAY_ACTION_ID_61);
		
			GoodsOrder currGoodsOrder = new GoodsOrder();
			currGoodsOrder = goodsOrderService.selectByPrimaryKey(orderId);
		
			if (null!=currGoodsOrder
					&&currGoodsOrder.getRunstatusid().intValue() == Constant.CONSTANTS_ORDER_RUNSTATUS_ID_1.intValue()) {
				goodsName = currGoodsOrder.getGoodsName();
				orderFee = currGoodsOrder.getTotal();
				
			} else {
				_resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3001);
				_resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3001_NOTE);
				return _resp;
			}
			
			/*************************************支付ACTION************************************************************/
				
				PayActionServerImpl impl = new PayActionServerImpl();
				
				Long payCashId = impl.cleanExpiredPayment(temOrderId,Constant.CONSTANTS_PAYMENT_WEIXIN);
				
				UnifiedorderResData resData;
				
				String openid = req.getOpenId();
				if (null!=payCashId) {
					resData = wXPayService.unifiedMiNiProgramorder("MiNiProgram", "首儿健康汇-" + goodsName, null, null,
							String.valueOf(payCashId)+"-"+String.valueOf(temOrderId), 
							String.valueOf(orderFee.setScale(2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100d)).intValue()),
							null, null, null,null, openid);
					//保存微信支付生成的字符串
					impl.updateWXNonceStrPaymentLog(payCashId, resData.getNonce_str());
				}else{
					_resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3001);
					_resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3001_NOTE);
					return _resp;
				}
				if (null == resData || resData.getReturn_code() == null) {
					logger
							.error("Case1:统一下单API请求逻辑错误，请仔细检测传过去的每一个参数是否合法，或是看API能否被正常访问");
					_resp
							.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_4001);
					_resp
							.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_4001_NOTE);
					return _resp;
				}

				if (resData.getReturn_code().equals("FAIL")) {
					// /注意：一般这里返回FAIL是出现系统级参数错误，请检测Post给API的数据是否规范合法
					logger
							.error("Case2:统一下单API系统返回失败，请检测Post给API的数据是否规范合法");
					_resp
							.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_4001);
					_resp
							.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_4001_NOTE);
					return _resp;
				} else {
					if (!Signature
							.checkIsSignValidFromResponseString(resData
									.getUnifiedorderServiceResponseString())) {
						logger
								.error("Case3:统一下单请求API返回的数据签名验证失败，有可能数据被篡改了");
						_resp
								.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_4001);
						_resp
								.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_4001_NOTE);
						return _resp;
					}

					if (resData.getResult_code().equals("FAIL")) {
						logger.error("出错，错误码：" + resData.getErr_code()
								+ "     错误信息：" + resData.getErr_code_des());
						logger.error("Case4:【统一下单失败】");
						// 退款失败时再怎么延时查询退款状态都没有意义，这个时间建议要么再手动重试一次，依然失败的话请走投诉渠道进行投诉
						_resp
								.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_4001);
						_resp
								.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_4001_NOTE);
						return _resp;
					} else {
						// 退款成功
						logger.info("Case5:【统一下单成功】");
						_resp.setAppid(resData.getAppid());
						_resp.setNoncestr(resData.getNonce_str());
						_resp.setPackageName("prepay_id="+resData.getPrepay_id());
						_resp.setPartnerid(resData.getMch_id());
						_resp.setTimestamp(String.valueOf(DateUtils.millisSecond()));
						_resp.setSignType("MD5");
						String sign = MD5.getMd5(_resp.toUnencryptedString());
						_resp.setErrorCode(ResultCode.OPERATION_SUCCESS);
						_resp.setErrorMsg(ResultCode.OPERATION_SUCCESS_NOTE);
						_resp.setSign(sign);
						_resp.setPayAmount(String.valueOf(orderFee==null?0:orderFee.setScale(2)));
						return _resp;
					}
				
				
			}
		}

	}

	
	public IRegisterOrderService getRegisterOrderService() {
		return registerOrderService;
	}

	public void setRegisterOrderService(
			IRegisterOrderService registerOrderService) {
		this.registerOrderService = registerOrderService;
	}

	public IGoodsPriceListService getGoodsPriceListService() {
		return goodsPriceListService;
	}

	public void setGoodsPriceListService(
			IGoodsPriceListService goodsPriceListService) {
		this.goodsPriceListService = goodsPriceListService;
	}

	public ISubRegisterOrderService getSubRegisterOrderService() {
		return subRegisterOrderService;
	}

	public void setSubRegisterOrderService(
			ISubRegisterOrderService subRegisterOrderService) {
		this.subRegisterOrderService = subRegisterOrderService;
	}

	public IGoodsOrderService getGoodsOrderService() {
		return goodsOrderService;
	}

	public void setGoodsOrderService(IGoodsOrderService goodsOrderService) {
		this.goodsOrderService = goodsOrderService;
	}

	public IUserCardListService getUserCardListService() {
		return userCardListService;
	}

	public void setUserCardListService(IUserCardListService userCardListService) {
		this.userCardListService = userCardListService;
	}
}
